package com.itheima.reggie.web;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.github.pagehelper.PageInfo;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.pojo.Category_分类;
import com.itheima.reggie.pojo.DishFlavor_菜品口味;
import com.itheima.reggie.pojo.Dish_菜品;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: cl
 * @Date: 2022/4/3 - 04 - 03
 * @Description:
 */

@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {

    //菜品
    @Autowired
    private DishService dishService;


    //菜品分类
    @Autowired
    private CategoryService categoryService;

    //菜品口味
    @Autowired
    private DishFlavorService dishFlavorService;

    //redis
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增菜品并添加口味
     *
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto) {
        log.info(dishDto.toString());

        dishService.saveWithFlavor(dishDto);

        //新增菜品后需要删除redis缓存中的菜品数据，保证缓存中菜品数据的正确性
        //两种方式：1、直接全部清空缓存    2、清空添加的本类菜品数据(推荐使用)

        //方式1：
//        Set keys = redisTemplate.keys("dish_*");//获取到菜品所有的key
//        redisTemplate.delete(keys);//全部删除

        //方式2：
        String key = "dish_" + dishDto.getCategoryId() + "_1";//菜品所属类的key
        redisTemplate.delete(key);

        return R.success("添加菜品成功！");

    }

    //自定义分页展示并查询菜品分类名字
    @GetMapping("/page")
    public R<Page> page(String name, int page, int pageSize) {
        PageInfo<DishDto> search = dishService.search(name, page, pageSize);
        Page<DishDto> p = new Page<>();
        p.setTotal(search.getTotal());
        p.setRecords(search.getList());
        return R.success(p);
    }


    /**
     * 分页展示并查询菜品分类名字
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */

//    @GetMapping("/page")
//    public R<Page> page(int page, int pageSize, String name) {
//        //构造分页对象
//        Page<Dish_菜品> pageInfo = new Page(page, pageSize);
//        Page<DishDto> dishDtoPage = new Page();
//
////    方式一：
////        //条件构造器
////        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
////        //添加过滤条件
////        queryWrapper.like(name != null,Dish::getName,name);
////        //添加排序条件
////        queryWrapper.orderByDesc(Dish::getUpdateTime);
////
////        //执行分页查询
////        dishService.page(pageInfo,queryWrapper);
//
//        //方式二：
//        dishService.page(pageInfo,
//                Wrappers.<Dish_菜品>lambdaQuery()
//                        .like(name != null, Dish_菜品::getName, name)
//                        .eq(Dish_菜品::getIsDeleted,0)
//                        .orderByDesc(Dish_菜品::getUpdateTime)
//        );
//
//        //拷贝对象
//        BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
//
//        List<Dish_菜品> records = pageInfo.getRecords();
//        //通过stream流操作集合
//        List<DishDto> list = records.stream().map((item) -> {
//
//            DishDto dishDto = new DishDto();
//            BeanUtils.copyProperties(item, dishDto);
//
//            Long categoryId = item.getCategoryId();//分类id
//            //根据id查询分类对象
//            Category_分类 category = categoryService.getById(categoryId);
//
//            //如果存在，就把让dishDao记录名字
//            if (category != null) {
//                String categoryName = category.getName();
//                dishDto.setCategoryName(categoryName);
//            }
//            return dishDto;
//        }).collect(Collectors.toList());
//
//        dishDtoPage.setRecords(list);
//        return R.success(dishDtoPage);
//    }

    /**
     * 根据id查询菜品和口味
     *
     * @param id
     * @return
     */

    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable long id) {
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品信息和对应口味
     *
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto) {
        dishService.updateWithFlavor(dishDto);

        //方式1、清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*"); //获取所有以dish_xxx开头的key
        redisTemplate.delete(keys); //删除这些key

        //方式2、清理某个分类下面的菜品缓存数据
//        String key = "dish_" + dishDto.getCategoryId() + "_1";
//        redisTemplate.delete(key);

        return R.success("菜品信息修改成功！");
    }

    /**
     * 获取菜品分类下的各个在售菜品
     *
     * @param dish
     * @return
     */
//    @GetMapping("/list")
//    public R<List<Dish_菜品>> list(Dish_菜品 dish) {
//
//        //根据categoryId查询
//        List<Dish_菜品> list = dishService.list(
//                Wrappers.<Dish_菜品>lambdaQuery()
//                        .eq(dish.getCategoryId() != null, Dish_菜品::getCategoryId, dish.getCategoryId())
//                        //添加条件，查询状态为1（起售状态）的菜品
//                        .eq(Dish_菜品::getStatus, 1)
//                        .orderByDesc(Dish_菜品::getSort).orderByAsc(Dish_菜品::getUpdateTime)
//        );
//        return R.success(list);
//    }


    /**
     * 获取菜品分类下的各个在售菜品  以及菜品口味(手机端需要用)
     *
     * @param dish
     * @return
     */
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish_菜品 dish) {

        List<DishDto> dtoList = null;

        //构造需要存入redis菜品数据的key：dish_1397844391040167938_1
        String key = "dish_" + dish.getCategoryId();
        //先从redis中获取缓存的菜品数据，如果获取不到再查数据库
        dtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        if (dtoList != null) {
            //如果存在，直接返回redis缓存中的菜品数据,不用再查询数据库
            return R.success(dtoList);
        }


        //根据categoryId查询
        List<Dish_菜品> list = dishService.list(
                Wrappers.<Dish_菜品>lambdaQuery()
                        .eq(dish.getCategoryId() != null, Dish_菜品::getCategoryId, dish.getCategoryId())
                        //添加条件，查询状态为1（起售状态）的菜品
                        .eq(Dish_菜品::getStatus, 1)
                        .orderByDesc(Dish_菜品::getSort).orderByAsc(Dish_菜品::getUpdateTime)
        );


        //查询菜品口味并合并
        dtoList = list.stream().map((item) -> {
            //1、把Dish_菜品里得东西复制给dishDto
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);

            //2、查询分类得名字并复制给dishDto
            Long categoryId = item.getCategoryId();
            Category_分类 category = categoryService.getById(categoryId);
            if (category != null) {
                dishDto.setCategoryName(category.getName());
            }

            //3、查询口味并复制给dishDto
            Long id = item.getId();
            List<DishFlavor_菜品口味> flavor_菜品口味s = dishFlavorService.list(
                    Wrappers.<DishFlavor_菜品口味>lambdaQuery()
                            .eq(DishFlavor_菜品口味::getDishId, id)
            );
            dishDto.setFlavors(flavor_菜品口味s);
            return dishDto;
        }).collect(Collectors.toList());

        //如果redis中不存在，将查询到的数据放入缓存中，并设置过期时间
        redisTemplate.opsForValue().set(key, dtoList, 60, TimeUnit.MINUTES);

        return R.success(dtoList);
    }


    /**
     * 批量修改
     *
     * @param status
     * @param ids
     * @return
     */
    @PostMapping("/status/{status}")
    public R<String> update(@PathVariable int status, Long[] ids) {

        //方式1：
        //dishService.updateStatus(status, ids);

        //方式2：
        Dish_菜品 dish = new Dish_菜品();
        dish.setStatus(status);
        dishService.update(dish,
                Wrappers.<Dish_菜品>lambdaUpdate()
                        .in(Dish_菜品::getId, ids)
        );

        //方式3：
//        List<Dish_菜品> list = new ArrayList<>();
//        for (int i = 0; i < ids.length; i++) {
//            Dish_菜品 dish = new Dish_菜品();
//            dish.setStatus(status);
//            dish.setId(ids[i]);
//            list.add(dish);
//        }
//        dishService.updateBatchById(list);

        //方式一：遍历所有的菜品id集合，通过id查询菜品数据(菜品分类的id)
        for (Long id : ids) {
            Dish_菜品 dish1 = dishService.getById(id);
            //获取菜品分类的id，拼装key，并根据key清理redis缓存
            String key = "dish_" + dish1.getCategoryId() + "_1";
            redisTemplate.delete(key);
        }

        //方式二：直接全部清空
//        Set keys = redisTemplate.keys("dish_*");
//        redisTemplate.delete(keys);


        return R.success("修改成功！");
    }

    /**
     * 批量删除菜品并删除对应口味和套餐中的菜品
     *
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(Long[] ids) {
//        List<Long> longs = Arrays.asList(ids);
//        dishService.removeByIds(longs);
        dishService.removeByIdsWithFlavorAndSetmealDish(ids);

        //方式一：遍历所有的菜品id集合，通过id查询菜品数据(菜品分类的id)
        for (Long id : ids) {
            Dish_菜品 dish = dishService.getById(id);
            //获取菜品分类的id，拼装key，并根据key清理redis缓存
            String key = "dish_" + dish.getCategoryId() + "_1";
            redisTemplate.delete(key);
        }

        //方式二：直接全部清空
//        Set keys = redisTemplate.keys("dish_*");
//        redisTemplate.delete(keys);

        return R.success("删除成功！");
    }
}
